﻿// Created by Windward Studios - no copyright is claimed. This code can be used in
// any manner by anyone for any reason. There is no copyright of any kind on it. You may
// use it in commercial products. You may change it without sharing those changes.
// We ask that you keep the "created by Windward Studios" in a comment at the top.

// bugbug - need to create, test KailuaTest for all data types.
// bugbug - need to test insert.
// bugbug - test metadata, stored procedures

using System.Collections.Specialized;
using System.Configuration;
using System.Data;
using System.Data.Common;
using net.windward.utils.ado.PostgreSql;
using NUnit.Framework;

namespace net.windward.utils.ado
{
	[TestFixture]
	public class TestPostgreSqlProvider
	{
		private string serverName;
		private string databaseName;
		private string username;
		private string password;

		private DbProviderFactory providerFactory;


		[SetUp]
		public void Init()
		{
			NameValueCollection appSettings = ConfigurationManager.AppSettings;
			serverName = appSettings["PostgreServer"];
			databaseName = appSettings["PostgreDatabase"];
			username = appSettings["PostgreUsername"];
			password = appSettings["PostgrePassword"];

			providerFactory = DbProviderFactories.GetFactory(WrPostgreSqlVendor.FactoryClass);
		}

		[Test]
		public void TestCreateProvider()
		{

			Assert.IsTrue(new WrPostgreSqlVendor().IsInstalled);

			WrPostgreSqlVendor vendor = (WrPostgreSqlVendor)WrProviderFactories.CreateProvider("My Sql name", null, WrPostgreSqlVendor.FactoryClass);
			Assert.IsNotNull(vendor);
			Assert.AreEqual(true, vendor.CanEnumerateDatabases);
			Assert.AreEqual(false, vendor.CanEnumerateServers);
			// bugbug: CanLaunchAdministrator returns false.
			//Assert.AreEqual(true, vendor.CanLaunchAdministrator);
//			Assert.AreEqual(true, vendor.CanRunScripts);
			Assert.AreEqual(false, vendor.CanUseTrustedConnection);
			Assert.AreEqual(WrVendor.DATABASE_MODE.REQUIRED, vendor.DatabaseMode);
			Assert.AreEqual(false, vendor.HasProviders);
			Assert.AreEqual("My Sql name", vendor.Name);
			Assert.AreEqual(string.Format("HOST={0};DATABASE={1};USER ID={2};PASSWORD={3}", serverName, databaseName, username, password),
				vendor.ConnectionString(serverName, databaseName, new WrCredentials(username, password), true));
		}

		[Test]
		public void TestPagilaEnumeration()
		{

			// enum databases, make sure has test one
			WrPostgreSqlServer server = new WrPostgreSqlServer(providerFactory, serverName);
			Assert.AreEqual(serverName, server.Name);
			IWrDatabase[] databases = server.GetDatabases(new WrCredentials(username, password));
			Assert.IsTrue(databases.Length > 0);
			WrPostgreSqlDatabase db = null;
			foreach (IWrDatabase dbOn in databases)
			{
				Assert.IsTrue(dbOn is WrPostgreSqlDatabase);
				if (dbOn.Name == databaseName)
					db = (WrPostgreSqlDatabase)dbOn;
			}
			Assert.IsNotNull(db);

			// Sakila tables
			db.LoadMetadata(new WrCredentials(username, password), WrVendor.ELEM_OWNER.ALL, null);
			WrTable[] tables = db.Tables;
			Assert.AreEqual(68, tables.Length);

			db.LoadMetadata(new WrCredentials(username, password), WrVendor.ELEM_OWNER.SYSTEM, null);
			tables = db.Tables;
			Assert.AreEqual(47, tables.Length);

			db.LoadMetadata(new WrCredentials(username, password), WrVendor.ELEM_OWNER.USER, null);
			tables = db.Tables;
			Assert.AreEqual(21, tables.Length);
			Assert.AreEqual("actor", tables[0].FullName);
			Assert.IsFalse(tables[0].IsSystem);
			Assert.AreEqual("", tables[0].Description);
			Assert.AreEqual("store", tables[20].FullName);
			Assert.IsFalse(tables[20].IsSystem);
			Assert.AreEqual("", tables[20].Description);

			// Sakila views
			db.LoadMetadata(new WrCredentials(username, password), WrVendor.ELEM_OWNER.ALL, null);
			WrView[] views = db.Views;
			Assert.AreEqual(83, views.Length);

			db.LoadMetadata(new WrCredentials(username, password), WrVendor.ELEM_OWNER.SYSTEM, null);
			views = db.Views;
			Assert.AreEqual(73, views.Length);

			db.LoadMetadata(new WrCredentials(username, password), WrVendor.ELEM_OWNER.USER, null);
			views = db.Views;
			Assert.AreEqual(10, views.Length);
			Assert.AreEqual("actor_info", views[0].FullName);
			Assert.IsFalse(views[0].IsSystem);
			Assert.AreEqual("", views[0].Description);
			Assert.AreEqual("staff_list", views[9].FullName);
			Assert.IsFalse(views[9].IsSystem);
			Assert.AreEqual("", views[0].Description);

			// Sakila stored procedures
			db.LoadMetadata(new WrCredentials(username, password), WrVendor.ELEM_OWNER.ALL, null);
			WrStoredProcedure[] procs = db.StoredProcedures;
			Assert.AreEqual(0, procs.Length);

			db.LoadMetadata(new WrCredentials(username, password), WrVendor.ELEM_OWNER.SYSTEM, null);
			procs = db.StoredProcedures;
			Assert.AreEqual(0, procs.Length);

			db.LoadMetadata(new WrCredentials(username, password), WrVendor.ELEM_OWNER.USER, null);
			procs = db.StoredProcedures;
			Assert.AreEqual(0, procs.Length);

			// staff columns
			db.LoadMetadata(new WrCredentials(username, password), WrVendor.ELEM_OWNER.USER | WrVendor.ELEM_OWNER.META_DATA, null);
			WrColumn[] cols = db.Tables[6].Columns;
			Assert.AreEqual(11, cols.Length);
			Assert.AreEqual("staff_id", cols[0].FullName);
			Assert.AreEqual(DbType.Int32, cols[0].DbType);
			Assert.AreEqual("", cols[0].Description);
			Assert.AreEqual(null, cols[0].PrimaryKey);
			Assert.AreEqual("last_update", cols[9].FullName);
			Assert.AreEqual(DbType.DateTime, cols[9].DbType);
			Assert.AreEqual("", cols[9].Description);

			Assert.AreEqual("store_id", cols[5].FullName);
			Assert.AreEqual(DbType.Int16, cols[5].DbType);
			Assert.AreEqual("", cols[5].Description);
			Assert.AreEqual("store.store_id", cols[5].PrimaryKey);
		}
	}
}
